package com.xbongbong.sys.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserDepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserDepartmentModel;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 此类用于解析OptionalRangeEntity中成员，部门，角色，动态负责人
 * @author 吴峰
 * @date 2021/12/07 10:03
 */
@Component
@Slf4j
public class SysUserHelp {

    @Resource
    private UserDepartmentModel userDepartmentModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private UserModel userModel;
    /**
     * @author 吴峰
     * @date 2021-03-17 09:44
     * @param
     * @return com.xbongbong.paas.toolbox.wrap.UserVO
     */
    public UserVO getUserName(String corpid, String userId, String loginUserName, Integer flowStatus, String creatorId) {
        String creatName = "";
        if(StringUtil.isNotEmpty(creatorId)){
            // 走审批时获取创建人id
            UserEntity user = userModel.getByKeyIngoreDel(creatorId, corpid);
            if (Objects.nonNull(user)){
                creatName = user.getName();
            }
        }

        String userName = Objects.equals(flowStatus, 2) ? creatName : loginUserName;
        if (Objects.equals(userId, PaasConstant.OUT_LINK_USER_ID)) {
            userName = PaasConstant.OUT_LINK_USER_NAME;
        }
        userId = Objects.equals(flowStatus, 2) ? creatorId : userId;
        UserVO userVO = new UserVO();
        userVO.setUserId(userId);
        userVO.setName(userName);
        userVO.setCorpid(corpid);
        return userVO;
    }
    /**
     * 用于人员解析
     * @param corpid
     * @param list 可选范围实体
     * @param data 数据实体， 请将负责人和协同人放入data中
     * @param creatorId 数据创建人
     * @return
     */
    public  Set<String> getUserListByOptionalRange(String corpid,  List<OptionalRangeEntity> list, JSONObject data, String creatorId) {

        Set<String> userSet = new HashSet<>();
        if (CollectionsUtil.isEmpty(list)) {
            return userSet;
        }
        Set<String> userList = new HashSet<>();
        Set<String> roleList = new HashSet<>();
        Set<String> departmentList = new HashSet<>();
        // 字段attr对应的级别{attr: [level0,level1]}
        Map<String, List<String>> dynamicLevelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (OptionalRangeEntity item : list) {
            if(Objects.equals(OptionalRangeEnum.MANAGER.getValue(), item.getProperty())) {
                setDynamicMap(dynamicLevelMap, FieldTypeEnum.CREATORID.getAlias(), item.getId());
            } else if(Objects.equals(OptionalRangeEnum.DYNAMIC_MANAGER.getValue(), item.getProperty())) {
                setDynamicMap(dynamicLevelMap, item.getAttr(), item.getId());
            } else if (Objects.equals(OptionalRangeEnum.USER.getValue(), item.getProperty())) {
                userList.add(item.getId());
            } else if (Objects.equals(OptionalRangeEnum.DEPT.getValue(), item.getProperty())) {
                departmentList.add(item.getId());
            } else if (Objects.equals(OptionalRangeEnum.ROLE.getValue(), item.getProperty())) {
                roleList.add(item.getId());
            }
        }
        // 字段attr对应的员工id {attr:[userId1,userId2]}
        Map<String, List<String>> dynamicManagerMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> dynamicUserIds = new ArrayList<>();
        for(Map.Entry<String, List<String>> entry : dynamicLevelMap.entrySet()) {
            String key = entry.getKey();
            // 创建人不从数据里取
            if(Objects.equals(FieldTypeEnum.CREATORID.getAlias(), key)) {
                dynamicManagerMap.put(key, Collections.singletonList(creatorId));
                dynamicUserIds.add(creatorId);
                continue;
            }

            // 数据里取对应的审批节点的动态负责人
            Object valueObj = data.get(key);
            if(!Objects.isNull(valueObj)) {
                List<String> ls = new ArrayList<>();
                if(valueObj instanceof List) {
                    ls.addAll(JSON.parseArray(JSON.toJSONString(valueObj), String.class));
                } else {
                    ls.add(String.valueOf(valueObj));
                }
                dynamicManagerMap.put(key, ls);
                dynamicUserIds.addAll(ls);
            }
        }

        try {
            userList.addAll(getUserListByDynamic(dynamicUserIds, corpid, dynamicManagerMap, dynamicLevelMap, userSet));
        } catch (Exception e) {
            log.error("com.xbongbong.sys.help.SysUserHelp.getUserListByOptionalRange", e);
        }

        userSet.addAll(getUserIdList(corpid, userList));

        // role的处理
        userSet.addAll(getUserIdListByRole(corpid, roleList));

        // department的处理
        userSet.addAll(getUserIdListByDepartment(corpid, departmentList));

        return userSet;
    }

    /**
     * 获取动态负责人以及顶级主管
     * @param dynamicUserIds
     * @param corpid
     * @param dynamicManagerMap
     * @param dynamicLevelMap
     * @param userSet
     * @return
     */
    public Set<String> getUserListByDynamic(List<String> dynamicUserIds, String corpid, Map<String, List<String>> dynamicManagerMap, Map<String, List<String>> dynamicLevelMap, Collection<String> userSet) throws XbbException {
        if(dynamicUserIds.isEmpty()) {
           return new HashSet<>();
        }
        // 获取公司的所有部门
        List<DepartmentEntity> allDepList = departmentModel.findAllDepartment(corpid, true);
        Map<Long, DepartmentEntity> allDepMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (DepartmentEntity department : allDepList) {
            allDepMap.put(department.getId(), department);
        }

        // 顶级主管
        DepartmentEntity topDepart = allDepMap.get(1L);
        List<String> topUserIds = userDepartmentModel.getDepManagerList(topDepart);
        Map<String, List<UserDepartmentEntity>> userDepartMap = getUserDepartmentMap(corpid, dynamicUserIds);

        // 所有要查询的部门
        Set<Long> deptList = new HashSet<>();
        for (Map.Entry<String, List<String>> entry : dynamicManagerMap.entrySet()) {
            String key = entry.getKey();
            List<String> users = entry.getValue();
            List<String> levels = dynamicLevelMap.get(key);

            for (String userId : users) {
                List<UserDepartmentEntity> userDepartmentEntities = userDepartMap.getOrDefault(userId, new ArrayList<>());
                getUserIdAndDepartmentId(userDepartmentEntities, allDepMap, levels, userSet, userId, topUserIds, deptList);
            }
        }
        return getUserIdIsLeader(corpid, deptList);
    }

    /**
     * 获取用户部门关联信息
     * @param corpid
     * @param dynamicUserSet 用户id列表
     * @return 用户部门信息
     */
    public Map<String, List<UserDepartmentEntity>> getUserDepartmentMap(String corpid, Collection<String> dynamicUserSet) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("userIdIn", dynamicUserSet);
        List<UserDepartmentEntity> userDepartmentList = userDepartmentModel.findEntitys(param);
        // 人员及其部门的map
        Map<String, List<UserDepartmentEntity>> userDepartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(userDepartmentList)) {
            userDepartmentList.forEach(v -> userDepartMap.computeIfAbsent(v.getUserId(), i -> new ArrayList<>()).add(v));
        }
        return userDepartMap;
    }

    /**
     * 返回部门和用户
     * @param userDepartmentEntities
     * @param departMap
     * @param levels
     * @param userIds 返回的用户列表
     * @param userId 当前负责人（负责人、协同人、创建人、成员单/多选）
     * @param topUserIds 顶部主管
     * @param deptList 返回的级别的主管
     * @return void
     * @author 吴峰
     * @date 2022/2/23 15:36
     */
    public void getUserIdAndDepartmentId(List<UserDepartmentEntity> userDepartmentEntities, Map<Long, DepartmentEntity> departMap, List<String> levels,
                                            Collection<String> userIds, String userId, List<String> topUserIds, Set<Long> deptList) {
        for (UserDepartmentEntity userDepartmentEntity : userDepartmentEntities) {
            DepartmentEntity departmentEntity = departMap.get(userDepartmentEntity.getDepartmentId());
            if (Objects.isNull(departmentEntity)) {
                continue;
            }
            // 当前user是否是部门主管
            boolean isLeader = Objects.equals(userDepartmentEntity.getIsLeader(), 1);
            List<Long> routDepIds = StringUtil.toLongList(departmentEntity.getDepIdRouter(), "|");
            int size = routDepIds.size();

            for (String level : levels) {
                int levelInt = Integer.parseInt(level);
                if (isLeader && levelInt > 0) {
                    levelInt++;
                }
                // 顶级主管
                if (levelInt > size || levelInt == -1) {
                    userIds.addAll(topUserIds);
                } else if (levelInt == 0) {
                    // 当前负责人（负责人、协同人、创建人、成员单/多选）
                    userIds.add(userId);
                } else {
                    // 级别的主管
                    Long depId = routDepIds.get(size - levelInt);
                    deptList.add(depId);
                }
            }
        }
    }

    /**
     * 根据部门id获取部门主管的用户
     * @param corpid
     * @param deptList 部门列表
     * @return
     */
    public Set<String> getUserIdIsLeader(String corpid, Collection<Long> deptList) {
        Set<String> userIds = new HashSet<>();
        if (CollectionsUtil.isEmpty(deptList)) {
            return userIds;
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("isLeader", 1);
        param.put("departmentIdIn", deptList);
        List<UserDepartmentEntity> userDepartList = userDepartmentModel.findEntitys(param);
        if (Objects.nonNull(userDepartList)) {
            userDepartList.forEach(v -> userIds.add(v.getUserId()));
        }
        return userIds;
    }

    /**
     * 获取用户信息
     * @param corpid
     * @param userIds
     * @return
     */
    public Set<String> getUserIdList(String corpid, Collection<String> userIds) {
        Set<String> userIdList = new HashSet<>();
        if (CollectionsUtil.isEmpty(userIds)) {
            return userIdList;
        }
        // 去除离职人员
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(StringConstant.CORPID, corpid);
        // 排除离职员工
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("userIdIn", userIds);
        List<UserEntity> userEntities = userModel.findEntitys(params);
        if (Objects.nonNull(userEntities)) {
            userEntities.forEach(v -> userIdList.add(v.getUserId()));
        }
        return userIdList;
    }


    /**
     * 根据角色获取用户
     * @param corpid
     * @param roles
     * @return
     */
    public Set<String> getUserIdListByRole(String corpid, Collection<String> roles) {
        Set<String> userIdList = new HashSet<>();
        if (CollectionsUtil.isEmpty(roles)) {
            return userIdList;
        }
        // 去除离职人员
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(StringConstant.CORPID, corpid);
        // 排除离职员工
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        if (!roles.isEmpty()) {
            params.put("roleIdIn", roles);

            List<UserEntity> userEntities = userModel.findEntitys(params);
            if (Objects.nonNull(userEntities)) {
                userEntities.forEach(v -> userIdList.add(v.getUserId()));
            }
        }
        return userIdList;
    }

    /**
     * 根据部门获取用户信息
     * @param corpid
     * @param departmentList
     * @return
     */
    public Set<String> getUserIdListByDepartment(String corpid, Collection<String> departmentList) {
        Set<String> userIdList = new HashSet<>();
        if (CollectionsUtil.isEmpty(departmentList)) {
            return userIdList;
        }
        // 去除离职人员
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(StringConstant.CORPID, corpid);
        // 排除离职员工
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        if (CollectionsUtil.isNotEmpty(departmentList)) {
            params.put("depIdIn", departmentList);

            List<UserEntity> userEntities = userModel.findEntitys(params);
            if (Objects.nonNull(userEntities)) {
                userEntities.forEach(v -> userIdList.add(v.getUserId()));
            }
        }
        return userIdList;
    }

    private void setDynamicMap(Map<String, List<String>> dynamicMap, String key, String value) {
        if(dynamicMap.containsKey(key)) {
            dynamicMap.get(key).add(value);
        } else {
            List<String> values = new ArrayList<>();
            values.add(value);
            dynamicMap.put(key, values);
        }
    }
}
